package com.lt.flashcard.model.service;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.shiro.crypto.hash.Md5Hash;

import com.lt.flashcard.Utility;
import com.lt.flashcard.model.entity.PhoneCardResponse;

public class PaymentService {

    private static final Logger log = Logger.getLogger(PaymentService.class);

    /**
     * Get the merchant id for this website
     * @return
     */
    private String getMerchantId() {
        return Utility.getConfiguration("com.lt.flashcard.payment_id", "");
    }

    private String getMerchantPassword() {
        return Utility.getConfiguration("com.lt.flashcard.payment_pass", "");
    }

    private String getPaymentReturnUrl() {
        return Utility.getConfiguration("com.lt.flashcard.payment_returnurl", "");
    }

    private String getPaymentVersion() {
        return Utility.getConfiguration("com.lt.flashcard.payment_version", "");
    }

    private String getPaymentCurrency() {
        return Utility.getConfiguration("com.lt.flashcard.payment_currency", "vnd");
    }

    private String getPaymentGateway() {
        return Utility.getConfiguration("com.lt.flashcard.payment_gateway", "");
    }

    public String getMerchantEmail() {
        return Utility.getConfiguration("com.lt.flashcard.payment_email", "");
    }

    /**
     * Generate the url for processing payment
     * @param transactioninfo
     * @param order_code
     * @param price
     * @param quantity
     * @param tax
     * @param discount
     * @param fee_shipping
     * @param order_description
     * @param buyer_name
     * @param buyer_email
     * @param buyer_phone
     * @param buyer_bankaddress
     * @param affiliate_code
     * @return
     */
    public String generatePaymentUrl(String transactioninfo, String order_code, int price, int quantity, int discount, int fee_shipping,
            String order_description, String buyer_name, String buyer_email, String buyer_phone, String buyer_bankaddress) {

        StringBuilder check = new StringBuilder();
        StringBuilder param = new StringBuilder();

        check.append(getMerchantId());
        param.append(String.format("%s=%s", "merchant_site_code", getMerchantId()));
        check.append(" " + getPaymentReturnUrl().toLowerCase());
        param.append(String.format("&%s=%s", "return_url", URLEncoder.encode(getPaymentReturnUrl().toLowerCase())));
        check.append(" " + getMerchantEmail());
        param.append(String.format("&%s=%s", "receiver", URLEncoder.encode(getMerchantEmail())));
        check.append(" " + transactioninfo);
        param.append(String.format("&%s=%s", "transaction_info", URLEncoder.encode(transactioninfo)));
        check.append(" " + order_code);
        param.append(String.format("&%s=%s", "order_code", URLEncoder.encode(order_code)));
        check.append(" " + String.valueOf(price));
        param.append(String.format("&%s=%s", "price", URLEncoder.encode(String.valueOf(price))));
        check.append(" " + getPaymentCurrency());
        param.append(String.format("&%s=%s", "currency", URLEncoder.encode(getPaymentCurrency())));
        check.append(" " + String.valueOf(quantity));
        param.append(String.format("&%s=%s", "quantity", URLEncoder.encode(String.valueOf(quantity))));
        check.append(" 0");
        param.append(String.format("&%s=%s", "tax", 0));
        check.append(" " + String.valueOf(discount));
        param.append(String.format("&%s=%s", "discount", URLEncoder.encode(String.valueOf(discount))));
        check.append(" 0");
        param.append(String.format("&%s=%s", "fee_cal", 0));
        check.append(" " + String.valueOf(fee_shipping));
        param.append(String.format("&%s=%s", "fee_shipping", URLEncoder.encode(String.valueOf(fee_shipping))));
        check.append(" " + order_description);
        param.append(String.format("&%s=%s", "order_description", URLEncoder.encode(order_description)));
        // check.append(" " + buyer_name + "*|*" + buyer_email + "*|*" + buyer_phone + "*|*" + buyer_bankaddress);
        check.append(" info");
        // param.append(String.format("&%s=%s", "buyer_info", URLEncoder.encode(buyer_name + "*|*" + buyer_email + "*|*" + buyer_phone + "*|*" +
        // buyer_bankaddress)));
        param.append("&buyer_info=info");
        check.append(" ");
        param.append(String.format("&%s=%s", "affiliate_code", ""));
        check.append(" " + getMerchantPassword());
        // add cancel_url
        param.append(String.format("&%s=%s", "cancel_url", URLEncoder.encode(getPaymentReturnUrl().toLowerCase() + "?cancel_code=" + order_code)));

        Md5Hash hash = new Md5Hash(check.toString());
        param.append(String.format("&%s=%s", "secure_code", hash.toString()));

        String url = getPaymentGateway();
        if (url.indexOf('?') > 0) {
            url = url + '&' + param.toString();
        } else {
            url = url + '?' + param.toString();
        }

        return url;
    }

    /**
     * Validate the return information from payment gateway
     * @param transaction
     * @param ordercode
     * @param price
     * @param payment_id
     * @param payment_type
     * @param error_text
     * @param secure_code
     * @return
     */
    public boolean checkPaymentReturnCode(String transaction, String ordercode, String price, String payment_id, String payment_type,
            String error_text, String secure_code) {
        StringBuilder check = new StringBuilder();
        check.append(" " + transaction);
        check.append(" " + ordercode);
        check.append(" " + price);
        check.append(" " + payment_id);
        check.append(" " + payment_type);
        check.append(" " + error_text);
        check.append(" " + String.valueOf(getMerchantId()));
        check.append(" " + getMerchantPassword());

        Md5Hash hash = new Md5Hash(check.toString());

        return secure_code.equals(hash.toString());
    }

    /**
     * Make request to service to process the phone card
     * @param pincard
     * @param serialcard
     * @param type
     * @param ordercode
     * @param email
     * @return
     */
    public PhoneCardResponse processPhoneCard(String pincard, String serialcard, String type, String ordercode, String email) {
        Map<String, String> param = new HashMap<String, String>();
        param.put("func", "CardCharge");
        param.put("version", "2.0");
        param.put("merchant_id", getMerchantId());
        param.put("merchant_account", getMerchantEmail());
        param.put("merchant_password", new Md5Hash(getMerchantId() + "|" + getMerchantPassword()).toString());
        param.put("pin_card", pincard);
        param.put("card_serial", serialcard);
        param.put("type_card", type);
        param.put("ref_code", ordercode);
        param.put("client_fullname", ordercode);
        param.put("client_email", email);
        param.put("client_mobile", "");
        String ret = Utility.wrapContentViaPOST("https://www.nganluong.vn/mobile_card.api.post.v2.php", param);
        PhoneCardResponse res = new PhoneCardResponse(ret);

        if (log.isInfoEnabled()) {
            log.info("Card response " + res.toString());
        }

        return res;
    }
}
